package org.iamd.hibernate;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.EntityMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.metadata.ClassMetadata;
import org.iamd.domain.business.ApplicationException;
import org.iamd.hibernate.vo.HibernateVO;

/**
 * Този клас се грижи за менажирането на Hibernate сесии.
 * 
 * @author И. Атанасов
 */
public class HibernateSessionFactory {

	/** Единствената инстанция - класът е singleton. */
	private static HibernateSessionFactory instance;

	/**
	 * @return единствената инстанция на фабриката
	 */
	public static HibernateSessionFactory getInstance() {
		if (instance == null) {
			instance = new HibernateSessionFactory();
		}
		return instance;
	}

	/** Фабриката на Hibernate. */
	private SessionFactory sessionFactory;

	/**
	 * Private конструктор, предотвратяващ директно инстанциране
	 */
	private HibernateSessionFactory() {
		// prevent instantiating
	}

	/**
	 * Връща текущата сесия за даден потребител.
	 * 
	 * @return стартирана сесия или активна такава
	 */
	public Session getSession() {
		return this.sessionFactory.getCurrentSession();
	}

	/**
	 * Инициализация на фабриката.
	 * 
	 * @param sessFactory
	 *            Hibernate фабрика
	 * 
	 * @throws ApplicationException
	 *             при неуспешна инициализация
	 */
	@SuppressWarnings("unchecked")
	void initializeFactory(SessionFactory sessFactory) throws ApplicationException {
		this.sessionFactory = sessFactory;
		List<Class<? extends HibernateVO>> vos = new ArrayList<Class<? extends HibernateVO>>();
		for (ClassMetadata value : this.sessionFactory.getAllClassMetadata().values()) {
			vos.add(value.getMappedClass(EntityMode.POJO));
		}
		// инициализиране на ИД стойностите за таблиците
		HibernateIdGenerator.getInstance().initKeys(vos);
	}

}